package study.kit.el.zh.parse;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONArray;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 纵横解析器
 */
@Slf4j
public class ZhParser {

    private static Configuration CONFIG = Configuration.builder()
            .options(Option.DEFAULT_PATH_LEAF_TO_NULL)
            .build();

    private ZhParser() {
    }

    /**
     * 读取头
     *
     * @param wholeJson
     * @return RowVO
     */
    public static RowVO parseHeader(String wholeJson) {
        // 验证
        if (StrUtil.isEmpty(wholeJson)) {
            return null;
        }
        // 第一行
        JSONArray row = JsonPath.using(CONFIG)
                .parse(wholeJson)
                .read("$.content.s1.rows[0]");
        return buildRowVO(row);
    }

    /**
     * 读取数据行
     *
     * @param wholeJson
     * @return List<RowVO>
     */
    public static List<RowVO> parseData(String wholeJson) {
        // 验证
        if (StrUtil.isEmpty(wholeJson)) {
            return null;
        }
        // 第二行开始
        JSONArray rows = JsonPath.using(CONFIG)
                .parse(wholeJson)
                .read("$.content.s1.rows[1:]");
        //log.info("{}", rows);
        //
        List<RowVO> rowVOLt = ListUtil.toList();
        for (Object row : rows) {
            //log.info("{}", row);
            rowVOLt.add(buildRowVO(row));
        }
        //log.info("{}", JSONUtil.toJsonStr(rowVOLt));
        return rowVOLt;
    }

    /**
     * 读取合并
     *
     * @param wholeJson
     * @return List<RangeVO>
     */
    public static List<RangeVO> parseRange(String wholeJson) {
        // 验证
        if (StrUtil.isEmpty(wholeJson)) {
            return null;
        }
        //
        JSONArray ranges = JsonPath.using(CONFIG)
                .parse(wholeJson)
                .read("$.modules.merge[*].range");
        //log.info("{}", ranges);
        //
        List<RangeVO> rangeVOLt = ranges.stream().map(e -> RangeVO.builder()
                        .rowNum(JsonPath.read(e, "$.[1]"))
                        .colNum(JsonPath.read(e, "$.[2]"))
                        .rowCnt(JsonPath.read(e, "$.[3]"))
                        .colCnt(JsonPath.read(e, "$.[4]"))
                        .build())
                .collect(Collectors.toList());
        //log.info("{}", rangeVOLt);
        return rangeVOLt;
    }

    /**
     * 行大小
     *
     * @param wholeJson
     * @return Integer
     */
    public static Integer parseRowSize(String wholeJson) {
        // 验证
        if (StrUtil.isEmpty(wholeJson)) {
            return null;
        }
        // 列
        JSONArray rowNumArr = JsonPath.using(CONFIG)
                .parse(wholeJson)
                .read("$.content.s1.rows[*][0]");
        //log.info("{}", rowNumArr.getClass());
        //
        return Convert.toInt(JsonPath.read(rowNumArr, "$.max()"));
    }

    /**
     * 列大小
     *
     * @param wholeJson
     * @return Integer
     */
    public static Integer parseColSize(String wholeJson) {
        // 验证
        if (StrUtil.isEmpty(wholeJson)) {
            return null;
        }
        // 列
        JSONArray colNumArr = JsonPath.using(CONFIG)
                .parse(wholeJson)
                .read("$.content.s1.rows[*][2][*][0]");
        //log.info("{}", colNumArr);
        //
        return Convert.toInt(JsonPath.read(colNumArr, "$.max()"));
    }

    private static RowVO buildRowVO(Object _row) {
        //
        JSONArray row = (JSONArray) _row;
        Integer rowNum = (Integer) row.get(0);
        RowVO rowVO = RowVO.builder()
                .rowNum(rowNum)
                .build();
        //
        JSONArray cols = (JSONArray) row.get(2);
        List<CellVO> cellVOLt = cols.stream().map(e -> {
                    //log.info("{}", e);
                    return CellVO.builder()
                            .rowNum(rowNum)
                            .colNum(JsonPath.read(e, "$.[0]"))
                            .value(JsonPath.read(e, "$.[1].value"))
                            .build();
                })
                .collect(Collectors.toList());
        //
        rowVO.setCellVOLt(cellVOLt);
        return rowVO;
    }
}
